package neptune.web.client.view.components.dialogs;

import java.util.ArrayList;
import neptune.web.client.WebInterface;
import neptune.web.client.commands.OpenClusterViewCommand;
import neptune.web.client.model.cluster.SerializablePhysicalNode;
import neptune.web.client.model.topology.*;
import neptune.web.client.services.ClusterService;
import neptune.web.client.view.components.MessageWidget;
import neptune.web.client.view.input.IPInputValidator;
import neptune.web.client.view.input.MACInputValidator;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;


public class EditPhysicalMachineDialog extends DialogBox implements ClickListener 
{

	private TextBox textIdPhysicalMachine=new TextBox();
	private TextBox textNamePhysicalMachine=new TextBox();	
	private TextBox textDescPhysicalMachine=new TextBox();
	private TextBox textCPUname=new TextBox();
	private TextBox textCPUtype=new TextBox();
	private TextBox textCPUclock=new TextBox();
	private TextBox textCPUamount=new TextBox();
	private TextBox textRAM = new TextBox();
	private TextBox textHD = new TextBox();
	private TextBox textSSHPort = new TextBox();
	private TextBox textIpAddress = new TextBox();
	private TextBox textMAC=new TextBox();
	private PasswordTextBox textRootPasswd=new PasswordTextBox();
	
	
	private SerializablePhysicalNode sPhyNode;
	
	
	public EditPhysicalMachineDialog(SerializablePhysicalNode serPhyNode)
	{
		super(false, true);

		this.sPhyNode=serPhyNode;
		FlexTable mainPanel = new FlexTable();
		mainPanel.setWidth("95%");
		ScrollPanel mainPanelWrapper = new ScrollPanel(mainPanel);
		mainPanelWrapper.setHeight("350px");

		// ID
		Label labelID = new Label("ID");
		labelID.setStylePrimaryName("NodePropsDialog-label");
		this.textIdPhysicalMachine = new TextBox();
		this.textIdPhysicalMachine.setStylePrimaryName("NodePropsDialog-input");
		this.textIdPhysicalMachine.setEnabled(false);
		mainPanel.setWidget(0, 0, labelID);
		mainPanel.setWidget(0, 1, this.textIdPhysicalMachine );
		
		//Nome
		Label labelName = new Label("Name");
		labelName.setStylePrimaryName("NodePropsDialog-label");
		this.textNamePhysicalMachine = new TextBox();
		this.textNamePhysicalMachine.setStylePrimaryName("NodePropsDialog-input");
		//this.textIdPhysicalMachine.setEnabled(false);
		mainPanel.setWidget(1, 0, labelName);
		mainPanel.setWidget(1, 1, this.textNamePhysicalMachine );

		// DESCRIPTION
		Label labelDesc = new Label("Description");
		labelDesc.setStylePrimaryName("NodePropsDialog-label");
		this.textDescPhysicalMachine = new TextBox();
		this.textDescPhysicalMachine.setStylePrimaryName("NodePropsDialog-input");
		mainPanel.setWidget(2, 0, labelDesc);
		mainPanel.setWidget(2, 1, this.textDescPhysicalMachine );

		// CPU
		DisclosurePanel cpuPanel = new DisclosurePanel("CPU");
		cpuPanel.setStylePrimaryName("NodePropsDialog-inputPanel");
		cpuPanel.setAnimationEnabled(true);
		cpuPanel.setWidth("100%");
		mainPanel.setWidget(3, 0, cpuPanel);
		mainPanel.getFlexCellFormatter().setColSpan(3, 0, 2);

		FlexTable cpuTable = new FlexTable();
		cpuTable.setWidth("100%");
		cpuPanel.add(cpuTable);

		// cpu name
		Label cpuNameLabel = new Label("Name");
		cpuNameLabel.setStylePrimaryName("NodePropsDialog-label");
		this.textCPUname = new TextBox();
		this.textCPUname.setStylePrimaryName("NodePropsDialog-input");
		cpuTable.setWidget(0, 0, cpuNameLabel);
		cpuTable.setWidget(0, 1, this.textCPUname);

		// cpu type
		Label cpuTypeLabel = new Label("Type");
		cpuTypeLabel.setStylePrimaryName("NodePropsDialog-label");
		this.textCPUtype = new TextBox();
		this.textCPUtype.setStylePrimaryName("NodePropsDialog-input");
		cpuTable.setWidget(1, 0, cpuTypeLabel);
		cpuTable.setWidget(1, 1, this.textCPUtype);

		// cpu clock
		Label cpuClockLabel = new Label("Clock");
		cpuClockLabel.setStylePrimaryName("NodePropsDialog-label");
		this.textCPUclock = new TextBox();
		this.textCPUclock.setStylePrimaryName("NodePropsDialog-input");
		cpuTable.setWidget(2, 0, cpuClockLabel);
		cpuTable.setWidget(2, 1, this.textCPUclock);
		
		// cpu quantità
		Label cpuAmountLabel = new Label("Amount");
		cpuClockLabel.setStylePrimaryName("NodePropsDialog-label");
		this.textCPUamount = new TextBox();
		this.textCPUamount.setStylePrimaryName("NodePropsDialog-input");
		cpuTable.setWidget(3, 0, cpuAmountLabel);
		cpuTable.setWidget(3, 1, this.textCPUamount);

		// RAM
		Label ramLabel = new Label("RAM MBs");
		ramLabel.setStylePrimaryName("NodePropsDialog-label");
		this.textRAM = new TextBox();
		this.textRAM.setStylePrimaryName("NodePropsDialog-input");
		mainPanel.setWidget(4, 0, ramLabel);
		mainPanel.setWidget(4, 1, this.textRAM);

		// HD
		Label hdLabel = new Label("HardDisk GBs");
		hdLabel.setStylePrimaryName("NodePropsDialog-label");
		this.textHD = new TextBox();
		this.textHD.setStylePrimaryName("NodePropsDialog-input");
		mainPanel.setWidget(5, 0, hdLabel);
		mainPanel.setWidget(5, 1, this.textHD);

		/*
		// OS
		DisclosurePanel osPanel = new DisclosurePanel("Operative System");
		osPanel.setStylePrimaryName("NodePropsDialog-inputPanel");
		osPanel.setAnimationEnabled(true);
		osPanel.setWidth("100%");
		mainPanel.setWidget(5, 0, osPanel);
		mainPanel.getFlexCellFormatter().setColSpan(5, 0, 2);

		FlexTable osTable = new FlexTable();
		osTable.setWidth("100%");
		osPanel.add(osTable);

		// os name
		Label osNameLabel = new Label("Name");
		osNameLabel.setStylePrimaryName("NodePropsDialog-label");
		osName = new TextBox();
		osName.setEnabled(false);
		osName.setStylePrimaryName("NodePropsDialog-input");
		osTable.setWidget(0, 0, osNameLabel);
		osTable.setWidget(0, 1, osName);

		// os version
		Label osVersionLabel = new Label("Version");
		osVersionLabel.setStylePrimaryName("NodePropsDialog-label");
		osVersion = new TextBox();
		osVersion.setEnabled(false);
		osVersion.setStylePrimaryName("NodePropsDialog-input");
		osTable.setWidget(1, 0, osVersionLabel);
		osTable.setWidget(1, 1, osVersion);

		// os username
		Label osUsernameLabel = new Label("Username");
		osUsernameLabel.setStylePrimaryName("NodePropsDialog-label");
		osUsername = new TextBox();
		osUsername.setText("root");
		osUsername.setEnabled(false);
		osUsername.setStylePrimaryName("NodePropsDialog-input");
		osTable.setWidget(2, 0, osUsernameLabel);
		osTable.setWidget(2, 1, osUsername);

		// os password
		Label osPasswordLabel = new Label("Password");
		osPasswordLabel.setStylePrimaryName("NodePropsDialog-label");
		osPassword = new TextBox();
		osPassword.setStylePrimaryName("NodePropsDialog-input");
		osTable.setWidget(3, 0, osPasswordLabel);
		osTable.setWidget(3, 1, osPassword);
		*/
		
		// IP Address
		Label ipLabel = new Label("IP Address");
		ipLabel.setStylePrimaryName("NodePropsDialog-label");
		this.textIpAddress = new TextBox();
		this.textIpAddress.setStylePrimaryName("NodePropsDialog-input");
		mainPanel.setWidget(6, 0, ipLabel);
		mainPanel.setWidget(6, 1, this.textIpAddress);

		// SSH PORT
		Label sshLabel = new Label("Ssh port");
		sshLabel.setStylePrimaryName("NodePropsDialog-label");
		this.textSSHPort = new TextBox();
		this.textSSHPort.setStylePrimaryName("NodePropsDialog-input");
		mainPanel.setWidget(7, 0, sshLabel);
		mainPanel.setWidget(7, 1, this.textSSHPort);
		
		// Root password
		Label rootPasswdLabel = new Label("root password");
		rootPasswdLabel.setStylePrimaryName("NodePropsDialog-label");
		this.textRootPasswd = new PasswordTextBox();
		this.textRootPasswd.setStylePrimaryName("NodePropsDialog-input");
		mainPanel.setWidget(8, 0, rootPasswdLabel);
		mainPanel.setWidget(8, 1, this.textRootPasswd);
		
		// MAC Address
		Label macLabel = new Label("MAC address");
		macLabel.setStylePrimaryName("NodePropsDialog-label");
		this.textMAC = new TextBox();
		this.textMAC.setStylePrimaryName("NodePropsDialog-input");
		mainPanel.setWidget(9, 0, macLabel);
		mainPanel.setWidget(9, 1, this.textMAC);

		// BUTTON PANEL
		HorizontalPanel buttonPanel = new HorizontalPanel();
		Button buttonOK = new Button("Ok");
		buttonOK.addClickListener(this);
		buttonOK.setStylePrimaryName("NodePropsDialog-button");
		Button buttonCancel = new Button("Cancel");
		buttonCancel.addClickListener(this);
		buttonCancel.setStylePrimaryName("NodePropsDialog-button");
		buttonPanel.add(buttonOK);
		buttonPanel.add(buttonCancel);

		VerticalPanel vPanel = new VerticalPanel();
		vPanel.setWidth("100%");
		vPanel.add(mainPanelWrapper);
		vPanel.add(buttonPanel);
		vPanel.setCellHorizontalAlignment(buttonPanel,
				VerticalPanel.ALIGN_RIGHT);

		this.setWidget(vPanel);
		this.setText("Edit physical machine");

		// Styles
		mainPanelWrapper.setStylePrimaryName("NodePropsDialog-mainWrapper");
		mainPanel.setStylePrimaryName("NodePropsDialog-mainPanel");
		this.setStylePrimaryName("NodePropsDialog");
		
		// Riempio i campi
		
		this.textIdPhysicalMachine.setText(this.sPhyNode.getId());
		this.textNamePhysicalMachine.setText(this.sPhyNode.getName() );
		this.textDescPhysicalMachine.setText(this.sPhyNode.getDescription() );
		
		//CPU
		String cpuName = sPhyNode.getCpu().getName();
		String cpuType =sPhyNode.getCpu().getType();
		String cpuClock = String.valueOf( sPhyNode.getCpu().getClock() );
		String cpuAmount=String.valueOf( sPhyNode.getCpu().getAmount() );
		
		this.textCPUname.setText( cpuName );
		this.textCPUtype.setText( cpuType );
		this.textCPUclock.setText( cpuClock );
		this.textCPUamount.setText( cpuAmount );
		
		ArrayList<SerializableNetworkInterface> sni = new ArrayList<SerializableNetworkInterface>();
		sni = sPhyNode.getInterfaces();
		SerializableIPAddress sIPAddress=sni.get(0).getControlAddress();
		this.textIpAddress.setText(sIPAddress.getAddress());
		
		
		sni = sPhyNode.getInterfaces();
		SerializableMACAddress sMAC= sni.get(0).getMacAddress();
		this.textMAC.setText(sMAC.getAddress() );
		
		SerializableOperativeSystem serOperSystem = this.sPhyNode.getOperativeSystem();
		this.textRootPasswd.setText(serOperSystem.getAdminPassword() );
		
		this.textSSHPort.setText("22");
		this.textRAM.setText(String.valueOf(this.sPhyNode.getRam()));
		this.textHD.setText(String.valueOf(this.sPhyNode.getHd() ));
	}
	

	
	
	
	
	
	public void onClick(Widget sender) 
	{
		if (((Button) sender).getText().equalsIgnoreCase("Ok")) 
		{
			if(this.isInputDataValid())
			{	
				this.sPhyNode.setId(this.textIdPhysicalMachine.getText() );
				this.sPhyNode.setDescription(this.textDescPhysicalMachine.getText());
				this.sPhyNode.setName(this.textNamePhysicalMachine.getText() );

				ArrayList<SerializableNetworkInterface> sni = new ArrayList<SerializableNetworkInterface>();
				sni = this.sPhyNode.getInterfaces();
				SerializableNetworkInterface serNetworkInterface= sni.get(0);
				SerializableIPAddress oldIPAddress=serNetworkInterface.getControlAddress();
				serNetworkInterface.removeIpAddress(oldIPAddress);
				SerializableNetworkInterface sNetInterface=new SerializableNetworkInterface();
				sNetInterface.setBindingDescription("physical");
				SerializableIPAddress ipAddress=new SerializableIPAddress();
				ipAddress.setAddress(this.textIpAddress.getText());
				ipAddress.setSubnetMask("225.225.225.0");
				ipAddress.setControlAddress(true);
				ipAddress.setVersion(4);
				
				// CPU
				//CPU
				String cpuName = this.textCPUname.getText();
				String cpuType =this.textCPUtype.getText();
				int cpuClock = Integer.parseInt( this.textCPUclock.getText() );
				int cpuAmount = Integer.parseInt( this.textCPUamount.getText() );
				this.sPhyNode.getCpu().setName( cpuName );
				this.sPhyNode.getCpu().setType( cpuType );
				this.sPhyNode.getCpu().setClock( cpuClock );
				this.sPhyNode.getCpu().setAmount( cpuAmount);
				
				ArrayList<SerializableIPAddress> ipAddresses=new ArrayList<SerializableIPAddress>();
				ipAddresses.add(ipAddress);
				sNetInterface.setIpAddresses(ipAddresses);
				// Imposto il MAC Address
				SerializableMACAddress sMacAddress=new SerializableMACAddress();
				sMacAddress.setAddress(this.textMAC.getText());
				sNetInterface.setMacAddress(sMacAddress);
				sNetInterface.setInterfaceName("eth0");
				ArrayList<SerializableNetworkInterface> al=new ArrayList<SerializableNetworkInterface>();
				al.add(sNetInterface);
				this.sPhyNode.setInterfaces(al);
				
				SerializableOperativeSystem serOperSystem = this.sPhyNode.getOperativeSystem();
				serOperSystem.setAdminPassword(this.textRootPasswd.getText());
				this.sPhyNode.setOperativeSystem(serOperSystem);
				
				//TODO Impostare la porta SSH
				this.sPhyNode.setRam(Integer.valueOf( this.textRAM.getText() ));
				this.sPhyNode.setHd(Integer.valueOf(this.textHD.getText()));
				
				String message = "Edit physical machine ...";
				final PopupPanel popup = WebInterface.showMessageDialog(
						new MessageWidget(MessageWidget.LOADING, message), false);
				ClusterService.Util.getInstance().editPhysicalMachine(this.sPhyNode,new AsyncCallback<Boolean>()
				{
		            public void onFailure(Throwable caught) 
		            {
		            	popup.hide();
		            	String message=new String("Error Unable to edit physical machine from the cluster: "+caught.getMessage() );
		            	WebInterface.addMessageToConsoleAndShowDialog(message,true);
		            }

		            public void onSuccess(Boolean result) 
		            {
		            	popup.hide();
		            	String message=new String("The physical machine has been modify!");
		            	WebInterface.addMessageToConsoleAndShowDialog(message,false);
		            	OpenClusterViewCommand ocw=new OpenClusterViewCommand();
		            	ocw.execute();
		            }
		        });
				this.hide();
				this.resetWindow();
			}
			else
			{
				//i dati in ingresso non sono validi
			}
		}
		else
		{
			this.hide();
			this.resetWindow();
		}
	}
	
	private boolean isInputDataValid()
	{
		this.textIpAddress.removeStyleDependentName("error");
		this.textMAC.removeStyleDependentName("error");
		IPInputValidator  ipValidator=new IPInputValidator();
		if ( !ipValidator.isValid(this.textIpAddress.getText() ))
		{
			this.textIpAddress.addStyleDependentName("error");
			return false;
		}
		MACInputValidator macValidator=new MACInputValidator();
		if( !macValidator.isValid(this.textMAC.getText()))
		{
			this.textMAC.addStyleDependentName("error");
			return false;
		}
		return true;
	}
	
	private void resetWindow()
	{
		this.textIpAddress.removeStyleDependentName("error");
		this.textMAC.removeStyleDependentName("error");
		this.textDescPhysicalMachine.setText("");
		this.textIdPhysicalMachine.setText("");
		this.textMAC.setText("");
		this.textIpAddress.setText("");
		this.textRootPasswd.setText("");
		this.textSSHPort.setText("");
	}	

}
